package com.base.cn.platform.os.controller.agent.user;

import com.base.cn.platform.os.common.constants.ConfigName;
import com.base.cn.platform.os.common.controller.BaseController;
import com.base.cn.platform.os.common.mybatis.Pagination;
import com.base.cn.platform.os.common.utils.*;
import com.base.cn.platform.os.common.utils.result.ResultUtil;
import com.base.cn.platform.os.entity.agent.config.AgentConfig;
import com.base.cn.platform.os.entity.agent.user.AgentUser;
import com.base.cn.platform.os.service.agent.config.AgentConfigBiz;
import com.base.cn.platform.os.service.agent.user.AgentUserBiz;
import com.base.cn.platform.os.service.manage.user.user.CusUserService;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.util.*;

/**
 * 推广员Controller
 *
 * @author LIZHIPENG
 * @since 2018/5/7
 */
@RestController
@RequestMapping("/course")
public class AgentUserController extends BaseController {

    @Autowired
    private AgentUserBiz agentUserBiz;
    @Autowired
    private CusUserService cusUserService;
    @Autowired
    private AgentConfigBiz  agentConfigBiz;

    /**
     * 判断用户是否是推广员
     * @param userId 用户
     * @return true是，false否
     */
    @RequestMapping("/isAgentUser")
    public boolean isAgentUser(@RequestParam("userId") BigDecimal userId){
        AgentUser agentUser = agentUserBiz.findOne("userId="+userId+" and `status`=3",null);
        if(ObjectUtils.isNotEmpty(agentUser)){
            return true;
        }
        return false;
    }

    /**
     * 统计推广员数量
     * @param
     * @return BigDecimal
     */
    @RequestMapping("/count")
    public BigDecimal count(){
        return agentUserBiz.count("status = 3 or status = 4");
    }

    /**
     * 查询推广员列表（分页）
     * @param currentPage 页码
     * @param agentUser 条件
     * @param parentData 是否设置父级推广员：true：是，false：否
     * @param incomeData 是否设置收益信息：true：是，false：否
     * @param userData 是否设置前台关联用户：true：是，false：否
     * @param createUserData 是否设置后台创建用户：true：是，false：否
     * @return
     */
    @RequestMapping("/queryAgentUserListPage")
    public PageInfo<AgentUser> queryAgentUserListPage(@RequestParam(value = "currentPage", required = false, defaultValue = "1")int currentPage,
                                                      @RequestParam(value = "pageSize", required = false, defaultValue = "10") int pageSize,
                                                      @RequestBody AgentUser agentUser,
                                                      @RequestParam("parentData")boolean parentData,
                                                      @RequestParam("incomeData")boolean incomeData,
                                                      @RequestParam("userData")boolean userData,
                                                      @RequestParam("createUserData") boolean createUserData){
        Pagination page = new Pagination();
        page.setCurrentPage(currentPage);
        page.setPageSize(pageSize);
        return agentUserBiz.queryAgentUserListPage(page, agentUser,parentData, incomeData, userData, createUserData);
    }

    /**
     * 根据ID查询推广员
     * @param agentUserId 推广员ID
     * @param parentData 是否设置父级推广员：true：是，false：否
     * @param incomeData 是否设置收益信息：true：是，false：否
     * @param userData 是否设置前台关联用户：true：是，false：否
     * @param createUserData 是否设置后台创建用户：true：是，false：否
     * @return
     */
    @RequestMapping("/findAgentUserById")
    public AgentUser findAgentUserById(@RequestParam("agentUserId")BigDecimal agentUserId,
                                       @RequestParam("parentData") boolean parentData,
                                       @RequestParam("incomeData") boolean incomeData,
                                       @RequestParam("userData")boolean userData,
                                       @RequestParam("createUserData") boolean createUserData){
        return agentUserBiz.findAgentUserById(agentUserId, parentData, incomeData, userData, createUserData);
    }

    /**
     * 保存推广员
     * @param agentUser 推广员信息
     * @return Map<String,Object>
     */
    @RequestMapping("/saveAgentUser")
    public Map<String,Object> saveAgentUser(@RequestBody AgentUser agentUser){
        Optional<Map<String, Object>> verify = verifyAgentUser(agentUser);
        if(verify.isPresent()){
            return verify.get();
        }
        return agentUserBiz.saveAgentUser(agentUser);
    }

    /**
     * 修改状态
     * @param agentUserIds
     * @param status
     * @return
     */
    @RequestMapping("/updateAgentUserStatus")
    public Map<String, Object> updateAgentUserStatus(@RequestParam("agentUserIds")String agentUserIds,
                                                     @RequestParam("status")int status){
        return agentUserBiz.updateAgentUserStatus(agentUserIds, status);
    }

    /**
     * 删除推广员
     * @param agentUserId
     * @return
     */
    @RequestMapping("/deleteAgentUser")
    public Map<String, Object> deleteAgentUser(@RequestParam("agentUserId") BigDecimal agentUserId){
        agentUserBiz.deleteAgentUser(agentUserId);
        return ResultUtil.SUCCESS("删除成功");
    }

    /**
     * 审核推广员
     * @param agentUserId 推广员ID
     * @param flag 审核标识：true：通过，false：驳回
     * @param rejectedCause 驳回原因
     * @return Map<String, Object>
     */
    @RequestMapping("/aduitAgentUser")
    public Map<String, Object> aduitAgentUser(@RequestParam("agentUserId") BigDecimal agentUserId,
                                              @RequestParam("flag") boolean flag,
                                              @RequestParam(value = "rejectedCause", required = false) String rejectedCause){
        if(!DataUtil.idIsNotNull(agentUserId)){
            return ResultUtil.ERROR("系统繁忙，请稍后重试");
        }
        AgentUser agentUser = new AgentUser();
        agentUser.setId(agentUserId);
        if(flag){
            agentUser.setStatus(3);
        }else {
            if(StringUtils.isEmpty(rejectedCause) || StringUtils.isEmpty(rejectedCause.trim())){
                return ResultUtil.ERROR("请填写驳回原因");
            }
            agentUser.setRejectedCause(rejectedCause.trim());
            agentUser.setStatus(5);
        }
        agentUserBiz.aduitAgentUser(agentUser);
        return ResultUtil.SUCCESS("操作成功");
    }

    /**
     * 根据用户ID查询推广员
     * @param userId 用户ID
     * @return AgentUser
     */
    @RequestMapping("/findAgentUserByUserId")
    public AgentUser findAgentUserByUserId(@RequestParam("userId")BigDecimal userId,
                                           @RequestParam(value = "incomeData", required = false, defaultValue = "false") boolean incomeData,
                                           @RequestParam(value = "invite", required = false, defaultValue = "false") boolean invite,
                                           @RequestParam(value = "hasSettlement", required = false, defaultValue = "false") boolean hasSettlement){
        return agentUserBiz.findAgentUserByUserId(userId, incomeData, invite, hasSettlement);
    }

    /**
     * 访问推广中心前，校验推广员状态
     * @param userId 用户ID
     * @return Map<String, Object>
     */
    @RequestMapping("/checkAgentUser")
    public Map<String, Object> checkAgentUser(@RequestParam("userId")BigDecimal userId){
        AgentUser agentUser = agentUserBiz.findAgentUserByUserId(userId, false, false, false);
        if(ObjectUtils.isEmpty(agentUser)){
            return ResultUtil.SUCCESS(1);//跳转开通申请页面
        }
        if(1 == agentUser.getStatus() || 2 == agentUser.getStatus()){//待提交或待审核状态
            return ResultUtil.SUCCESS("您的申请正在审核中，请耐心等待", 3);
        }else if(3 == agentUser.getStatus()){
            return ResultUtil.SUCCESS(2);//跳转推广中心首页
        }else if(4 == agentUser.getStatus()){
            return ResultUtil.SUCCESS("推广员身份被冻结，请联系后台管理员", 3);
        }else {
            return ResultUtil.SUCCESS("申请被驳回，是否重新申请",4);
        }
    }

    /**
     * 申请开通推广员
     * @param userId 用户ID
     * @param shareKey 分享Key,用于获取分享来源用户
     * @return Map<String, Object>
     */
    @RequestMapping("/openExtension")
    public Map<String, Object> openExtension(@RequestParam("userId") BigDecimal userId,
                                             @RequestParam(value = "shareKey", required = false) String shareKey){
        if(!DataUtil.idIsNotNull(userId)){
            return ResultUtil.ERROR("请登录后再来开通");
        }
        AgentUser _agentUser = agentUserBiz.findAgentUserByUserId(userId, false, false, false);
        if(ObjectUtils.isEmpty(_agentUser)){//没有申请过
            Map<String, Object> user = cusUserService.userInfo(userId, false, false, false, false, false, false, false);
            if(ObjectUtils.isEmpty(user)){
                return ResultUtil.ERROR("系统繁忙，请稍后重试");
            }
            AgentUser agentUser = new AgentUser();
            agentUser.setAgentUserName((String)user.get("nickname"));
            agentUser.setMobile((String)user.get("mobile"));
            agentUser.setUserId(userId);
            agentUser.setDivideType(1);
            if(StringUtils.isNotEmpty(shareKey)){//二级分销员
                Map<String,Object> resultMap = setTwoAgent(shareKey,userId,agentUser);
                if(resultMap!=null){
                    return resultMap;
                }
            }else {//一级分销员
                //获取默认配置的分销收益比例
                Map<String, AgentConfig> stringAgentConfigMap = agentConfigBiz.queryAgentConfigList();
                AgentConfig agentConfig = stringAgentConfigMap.get(ConfigName.SALES_INCOME);
                agentUser.setUserType(1);
                agentUser.setParentId(BigDecimal.ZERO);
                if(ObjectUtils.isNotEmpty(agentConfig)){
                    Map<String, String> configMap = agentConfig.getConfigMap();
                    String oneScale = configMap.get("oneScale");
                    String twoScale = configMap.get("twoScale");
                    String bonusScale = configMap.get("bonusScale");
                    if(StringUtils.isEmpty(oneScale)){
                        agentUser.setOneScale(5);
                    }else{
                        agentUser.setOneScale(Integer.valueOf(oneScale));
                    }
                    if(StringUtils.isEmpty(twoScale)){
                        agentUser.setTwoScale(3);
                    }else{
                        agentUser.setTwoScale(Integer.valueOf(twoScale));
                    }
                    if(StringUtils.isEmpty(bonusScale)){
                        agentUser.setBonusScale(2);
                    }else{
                        agentUser.setBonusScale(Integer.valueOf(bonusScale));
                    }
                }else{
                    agentUser.setOneScale(5);
                    agentUser.setTwoScale(3);
                    agentUser.setBonusScale(2);
                }
            }
            agentUser.setSettType(2);//默认月结
            agentUser.setCreateFrom(2);//前台自申请
            return agentUserBiz.saveAgentUser(agentUser);
        }else if(_agentUser.getStatus()==1 || _agentUser.getStatus()==2){
            return ResultUtil.ERROR("您的申请正在审核中，请耐心等待");
        }else if(_agentUser.getStatus() == 3 || _agentUser.getStatus()==4){
            return ResultUtil.ERROR("您已经是推广员，不必再申请了");
        }else {//申请被驳回
            AgentUser agentUser = new AgentUser();
            agentUser.setId(_agentUser.getId());
            if(StringUtils.isNotEmpty(shareKey)) {//二级分销员
                Map<String,Object> resultMap = setTwoAgent(shareKey,userId,agentUser);
                if(resultMap!=null){
                    return resultMap;
                }
                agentUser.setStatus(3);
            }else{
                agentUser.setStatus(1);
            }
            return agentUserBiz.saveAgentUser(agentUser);
        }
    }

    /**
     * 批量导入推广员
     * @param file 文件对象
     * @return Map<String, Object>
     */
    @RequestMapping(value = "/uploadAgentUser", method = {RequestMethod.POST}, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Map<String, Object> uploadAgentUser(@RequestPart(value = "file") MultipartFile file){
        return agentUserBiz.uploadAgentUser(file);
    }

    /**
     * 查询推广员申请记录
     * @param agentUser 查询条件
     * @param parentData 是否设置上级推广员
     * @param incomeData 是否设置收益信息
     * @param userData 是否设置用户信息
     * @param createUserData 是设置创建人信息
     * @return List<AgentUser>
     */
    @RequestMapping("/queryAgentUserList")
    public List<AgentUser> queryAgentUserList(@RequestBody AgentUser agentUser,
                                              @RequestParam("parentData")boolean parentData,
                                              @RequestParam("incomeData")boolean incomeData,
                                              @RequestParam("userData")boolean userData,
                                              @RequestParam("createUserData") boolean createUserData){
        return agentUserBiz.queryAgentUserList(agentUser,parentData,incomeData,userData,createUserData);
    }

    @RequestMapping("/alterAgentSettType")
    public Map alterAgentSettType(@RequestParam("settType") int settType,@RequestParam("ids") String ids){
          return agentUserBiz.alterAgentSettType(settType,ids);
    }

    //=========================================================================

    /**
     * 设置二级推广员数据
     * @param shareKey
     * @param userId
     * @param agentUser
     * @return
     */
    private Map<String,Object> setTwoAgent(String shareKey, BigDecimal userId, AgentUser agentUser){
        String[] split = shareKey.split("_");
        if(!StringUtils.isNumber(split[1])){//上级分销用户ID
            return ResultUtil.ERROR();
        }
        BigDecimal shareUserId = new BigDecimal(split[1]);//通过shareKey获取分享者ID，然后查出父级推广员
        if(shareUserId.compareTo(userId) ==0){
            return ResultUtil.ERROR("不能申请成为自己的二级推广员");
        }
        //父级推广员
        AgentUser parentAgentUser = agentUserBiz.findAgentUserByUserId(shareUserId, false, false, false);
        if(parentAgentUser == null){
            return ResultUtil.ERROR("一级推广员不存在");
        }
        agentUser.setUserType(2);//二级推广员
        agentUser.setParentId(parentAgentUser.getId());
        agentUser.setOneScale(0);
        agentUser.setTwoScale(parentAgentUser.getTwoScale());
        agentUser.setBonusScale(0);
        agentUser.setStatus(3);
        return null;
    }

    private Optional<Map<String,Object>> verifyAgentUser(AgentUser agentUser){
        if(ObjectUtils.isEmpty(agentUser)){
            return Optional.of(ResultUtil.ERROR("保存信息为空，保存失败"));
        }
        if(ObjectUtils.isEmpty(agentUser.getUserType()) || (agentUser.getUserType() != 1 && agentUser.getUserType() != 2)){
            return Optional.of(ResultUtil.ERROR("推广员类型错误，保存失败"));
        }
        if(StringUtils.isEmpty(agentUser.getAgentUserName()) || StringUtils.isEmpty(agentUser.getAgentUserName().trim())){
            return Optional.of(ResultUtil.ERROR("推广员名称不能为空"));
        }
        if(!StringUtils.isMobile(agentUser.getMobile())){
            return Optional.of(ResultUtil.ERROR("手机号码不能为空"));
        }
        if(ObjectUtils.isEmpty(agentUser.getDivideType()) || agentUser.getDivideType()==0){
            return Optional.of(ResultUtil.ERROR("请选择分成比例"));
        }
        if(agentUser.getUserType() == 1){
            if(ObjectUtils.isEmpty(agentUser.getOneScale()) || agentUser.getOneScale() <0 || agentUser.getOneScale() >100){
                return Optional.of(ResultUtil.ERROR("一级分成比例输入有误，请重新输入"));
            }
            if(ObjectUtils.isEmpty(agentUser.getTwoScale()) || agentUser.getTwoScale() <0 || agentUser.getTwoScale() >100){
                return Optional.of(ResultUtil.ERROR("二级分成比例输入有误，请重新输入"));
            }
            if(ObjectUtils.isEmpty(agentUser.getBonusScale()) || agentUser.getBonusScale() <0 || agentUser.getBonusScale() >100){
                return Optional.of(ResultUtil.ERROR("奖励金比例输入有误，请重新输入"));
            }
            if(agentUser.getTwoScale() + agentUser.getBonusScale() > 100){
                return Optional.of(ResultUtil.ERROR("二级分成比例与奖励金比例之和不能大于100"));
            }
        }
        if(agentUser.getUserType()==2){
            if(!DataUtil.idIsNotNull(agentUser.getParentId())){
                return Optional.of(ResultUtil.ERROR("上级推广员为空，请选择"));
            }
            if(ObjectUtils.isEmpty(agentUser.getTwoScale())){
                return Optional.of(ResultUtil.ERROR("分成比例错误，保存失败"));
            }
            AgentUser parentAgentUser = agentUserBiz.findAgentUserById(agentUser.getParentId(), false, false, false, false);
            if(ObjectUtils.isEmpty(parentAgentUser) || agentUser.getTwoScale()!=parentAgentUser.getTwoScale()){
                return Optional.of(ResultUtil.ERROR("系统繁忙，请稍后重试"));
            }
        }
        if(ObjectUtils.isEmpty(agentUser.getCreateFrom()) || agentUser.getCreateFrom()==0){
            return Optional.of(ResultUtil.ERROR("创建来源为空，保存失败"));
        }
        if(ObjectUtils.isEmpty(agentUser.getSettType()) || (agentUser.getSettType() !=1 && agentUser.getSettType() !=2 && agentUser.getSettType()!=3)){
            return Optional.of(ResultUtil.ERROR("请正确选择结算周期"));
        }
        return Optional.empty();
    }

    /**
     * 导出推广员数据
     *
     * @param agentUser 推广员查询条件
     * @param pageSize
     * @return
     * @throws Exception
     */
    @RequestMapping("/downloadExcelAgentList")
    public ResponseEntity<byte[]> downloadExcelAgentList(@RequestBody AgentUser agentUser, @RequestParam("pageSize") int pageSize ) throws Exception{
        return exportAgentXls(agentUser,pageSize);
    }

    private ResponseEntity<byte[]> exportAgentXls(AgentUser condition, int pageSize) throws Exception {
        //表格头部
        String [] heads = new String[] {"ID","推广员名称","手机","推广员类型","分成类型","一级推广员分成比例","二级推广员分成比例","奖金分成比例","结算类型","创建来源","上级推广员ID","推广员的客户数量","下级推广员数量","状态","创建时间"};
        PageInfo<AgentUser> agentUserListPagePage = this.queryAgentUserListPage(1,pageSize,condition,true, true, false, false);
        return FileExportImportUtil.exportExcel(heads,getData(agentUserListPagePage.getList()),"推广员数据列表");
    }

    /**
     *获取推广员数据
     *
     * @param agentUserList 数据
     * @return
     */
    private List<List<String>> getData(List<AgentUser> agentUserList){
        List<List<String>> data = new ArrayList<>();
        agentUserList.forEach((v)->{
            String userType = "";
            switch (v.getUserType()){
                case 1:
                    userType = "一级推广员";
                    break;
                case 2:
                    userType = "二级推广员";
                    break;
            }
            String settType = "";
            switch (v.getSettType()){
                case 1:
                    settType = "随时结";
                    break;
                case 2:
                    settType = "月结";
                    break;
                case 3:
                    settType = "年结";
                    break;
            }
            String status = "";
            switch (v.getStatus()){
                case 1:
                    status = "待提交";
                    break;
                case 2:
                    status = "待审核";
                    break;
                case 3:
                    status = "正常";
                    break;
                case 4:
                    status = "禁用";
                    break;
                case 5:
                    status = "驳回";
                    break;
            }
            data.add(Arrays.asList(
                    v.getId().toString(),
                    v.getAgentUserName(),
                    v.getMobile(),
                    userType,
                    v.getDivideType() == 1?"固定分成比例":"",
                    v.getOneScale().toString()+"%",
                    v.getTwoScale().toString()+"%",
                    v.getBonusScale().toString()+"%",
                    settType,
                    v.getCreateFrom() == 1?"后台创建":"前台申请",
                    v.getParentId().toString(),
                    v.getCustomerNum().toString(),
                    v.getSunNum().toString(),
                    status,
                    ObjectUtils.isNotEmpty(v.getCreateTime())?DateUtils.format(v.getCreateTime(),"yyyy-MM-dd HH:mm:ss"):""
            ));
        });
        return  data;
    }
}
